package de.unihannover.hci.portraitquiz;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Application;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import de.unihannover.hci.portraitquiz.database.DatabaseHandler;
import de.unihannover.hci.portraitquiz.model.Answer;
import de.unihannover.hci.portraitquiz.model.Category;

public class PortraitQuiz extends Application {

	private Map<Integer, Category> categories;
	private Map<Integer, Map<Integer, Answer>> category2answers;
	private Category currentCategory;
	private boolean playSounds = true;
	public DatabaseHandler db;

	private Drawable obstacle = null;

	public Drawable getObstacle() {
		return obstacle;
	}

	public void setObstacle(Drawable obstacle) {
		this.obstacle = obstacle;
	}

	public void onCreate() {
		super.onCreate();

		db = new DatabaseHandler(this);

		categories = new HashMap<Integer, Category>();
		importData();
	}

	/**
	 * 
	 * @param id
	 * @return true if category set, false otherwise.
	 */
	public boolean setCurrentCategory(int id) {
		currentCategory = categories.get(id);
		if (currentCategory == null) {
			return false;
		}
		return true;
	}

	public Category getCurrentCategory() {
		return currentCategory;
	}

	public List<Category> getCategories() {
		ArrayList<Category> values = new ArrayList<Category>(categories.values());
		return values;
	}

	private void importData() {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		try {
			DocumentBuilder builder = factory.newDocumentBuilder();

			Resources resources = getResources();
			Document dom = builder.parse(resources.openRawResource(R.raw.categories));
			Element root = dom.getDocumentElement();
			NodeList items = root.getElementsByTagName("category");
			for (int i = 0; i < items.getLength(); i++) {
				Category category = new Category();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();
				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();

					if (name.equalsIgnoreCase("id")) {
						category.setId(Integer.parseInt(property.getFirstChild().getNodeValue()));
					} else if (name.equalsIgnoreCase("name")) {
						category.setName(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("image")) {
						category.setImage(property.getFirstChild().getNodeValue());
					}
				}
				categories.put(category.getId(), category);
			}

			dom = builder.parse(resources.openRawResource(R.raw.answers));
			root = dom.getDocumentElement();
			items = root.getElementsByTagName("answer");
			for (int i = 0; i < items.getLength(); i++) {
				Answer answer = new Answer();
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();
				for (int j = 0; j < properties.getLength(); j++) {
					Node property = properties.item(j);
					String name = property.getNodeName();

					if (name.equalsIgnoreCase("id")) {
						answer.setId(Integer.parseInt(property.getFirstChild().getNodeValue()));
					} else if (name.equalsIgnoreCase("category")) {
						answer.setCategory(Integer.parseInt(property.getFirstChild().getNodeValue()));
					} else if (name.equalsIgnoreCase("name")) {
						answer.setName(property.getFirstChild().getNodeValue());
					} else if (name.equalsIgnoreCase("image")) {
						answer.setImage(property.getFirstChild().getNodeValue());
					}
				}
				Category category = categories.get(answer.getCategory());
				category.addAnswer(answer);
				// Overwrite existing
				categories.put(category.getId(), category);
			}
		} catch (Exception e) {
			System.err.println("Kurwa");
			throw new RuntimeException(e);
		}
	}

	/**
	 * @return the type
	 */
	public Typeface getAppFontType() {
		return Typeface.createFromAsset(getAssets(), "fonts/44v2.ttf");
	}

	/**
	 * @return the playSounds
	 */
	public boolean playsSounds() {
		return playSounds;
	}

	/**
	 * @param playSounds
	 *            the playSounds to set
	 */
	public void setPlaySounds(boolean playSounds) {
		this.playSounds = playSounds;
	}

	/*
	 * Berechnungsmethode: Punktegrenzen sollen quadratisch steigen.
	 * Grundfunktion also f(x)=ax². Wir setzen auf Grundlage empirischer
	 * Untersuchungen die oberste Grenze fesyt mit f(5)=55000. Nun erhalten wir
	 * dank 55000=a*5² für a=2200. und damit die Punktegrenzen für x aus [1,5]:
	 * 2200, 8800, 19800, 35200, 55000.
	 */
	public int getStarsDrawableForScore(int points) {
		if (points < 2200) {
			return R.drawable.stars0;
		} else if (points < 8800) {
			return R.drawable.stars1;
		} else if (points < 19800) {
			return R.drawable.stars2;
		} else if (points < 35200) {
			return R.drawable.stars3;
		} else if (points < 55000) {
			return R.drawable.stars4;
		} else {
			return R.drawable.stars5;
		}
	}

	public int getStarsDrawableForCategory(int cat) {
		int points = db.getHighestScoreForCat(cat);
		return this.getStarsDrawableForScore(points);
	}

}
